#include "StdAfx.h"
#include <MyControls/Language.h>
#include <MyControls/App.h>
#include <MyControls/Resource.h>
#include <mswin/file_dir.h>
#include <xtd/functional>

namespace My {

static const char * suffixes[LANG_MAX] = {
	0,
	"enu",
	"rus"
};

String DLL_API GetLanguageSuffix(Language l)
{
	return suffixes[l];
}

String DLL_API GetLanguageName(Language l)
{
	return GetApp().LoadString(MY_LANG_FIRST + l);
}

std::list<DLLLanguage *>	BasicLanguage::m_DLLs;
AppLanguage *				BasicLanguage::m_pApp(0);

BasicLanguage::BasicLanguage() :
	m_hInstance(0),
	m_hModule(0),
	m_Language(LANG_NONE)
{
}

BasicLanguage::~BasicLanguage()
{
	UnloadModule();
}

void BasicLanguage::Init(HINSTANCE hInstance)
{
	assert(m_hInstance == 0);
	m_hInstance = hInstance;
}

void BasicLanguage::LoadModule(Language lang)
{
	if (GetModule() != 0)
		UnloadModule();
	assert(lang < LANG_MAX);
	if (lang == LANG_NONE)
		return;
	char buf[MAX_PATH];
	VERIFY(::GetModuleFileName(m_hInstance, buf, MAX_PATH));
	String path(buf);
	mswin::change_ext(path, suffixes[lang]);
	m_hModule = ::LoadLibrary(path.c_str());
	if (m_hModule != 0)
		m_Language = lang;
	else
		m_Language = LANG_NONE;
}

void BasicLanguage::UnloadModule()
{
	if (m_hModule != 0) {
		::FreeLibrary(m_hModule);
		m_hModule = 0;
		m_Language = LANG_NONE;
	}
}

// DLLLanguage

void DLLLanguage::Init(HINSTANCE hInstance)
{
	BasicLanguage::Init(hInstance);
	m_DLLs.push_back(this);
}

// AppLanguage

void AppLanguage::Init(const char * szSection, const char * szEntry)
{
	BasicLanguage::Init(GetApp().m_hInstance);
	assert(m_pApp == 0);
	m_pApp = this;
	m_Section = szSection;
	m_Entry = szEntry;

	LoadModule(GetStartupLanguage());
	if (GetModule() != 0)
		GetApp().SetLanguageModule(GetModule());

	xtd::for_each(m_DLLs,
		xtd::bind2nd(std::mem_fun1(LoadModule), GetLanguage()));
}

Language AppLanguage::GetStartupLanguage()
{
	if (m_Section.empty() || m_Entry.empty())
		return LANG_NONE;
	int value = int(GetApp().GetProfileInt(m_Section.c_str(), m_Entry.c_str(), LANG_NONE));
	if (value < int(LANG_NONE))
		return LANG_NONE;
	if (value >= int(LANG_MAX))
		return LANG_NONE;
	return Language(value);
}

void AppLanguage::SetStartupLanguage(Language lang)
{
	if (m_Section.empty() || m_Entry.empty())
		return;
	GetApp().WriteProfileInt(m_Section.c_str(), m_Entry.c_str(), int(lang));
}

} // My

